package sg.edu.nus.iss.vmcs.system;

import java.awt.Frame;
import java.util.Observable;
import java.util.Observer;

import sg.edu.nus.iss.vmcs.customer.CoinReceiver;
import sg.edu.nus.iss.vmcs.customer.CustomerUI;
import sg.edu.nus.iss.vmcs.interfaces.InterfaceFactory;
import sg.edu.nus.iss.vmcs.termination.states.CoinInsertedState;
import sg.edu.nus.iss.vmcs.termination.states.DispenseChangeState;
import sg.edu.nus.iss.vmcs.termination.states.DispenseDrinkState;
import sg.edu.nus.iss.vmcs.termination.states.InitialState;
import sg.edu.nus.iss.vmcs.termination.states.TerminateState;
import sg.edu.nus.iss.vmcs.termination.template.Termination;
import sg.edu.nus.iss.vmcs.termination.template.TerminationOnChangeGiving;
import sg.edu.nus.iss.vmcs.termination.template.TerminationOnDispense;
import sg.edu.nus.iss.vmcs.termination.template.TerminationOnStoringCoins;

public class TransactionController implements Observer{

	private MainController mainController;
	private CustomerUI customerPanel;
	private Observable coinReceiver;

	//priyanka- addition of the variable for encapsulating the state
	private DispenseController dispenseController=null;
	private int incoming=0;
	private TerminateState currentState=null;
	
	
	public TransactionController(MainController mainController) {
		System.out.println("@@@@@Observer: TransactionController(Observer) is created");
		this.mainController = mainController;	
		//Lin - getting Observable
		this.coinReceiver = new CoinReceiver(mainController.getStoreController(), this);
		//Lin - add this Observer into Observable
		coinReceiver.addObserver(this);		
		System.out.println("@@@@@Observer: TransactionController Observer is added to Observable");
		//priyanka - setting the state		
		this.dispenseController=new DispenseController();
		this.currentState=new InitialState();	
	}
	
	
	public void displayCustomerPanel(){
		VMCSControlUI scp = mainController.getSimulatorControlPanel();
		customerPanel = InterfaceFactory.getInstance().createCustomerUI(this, mainController);
		dispenseController.setCustomerUI(customerPanel);
		customerPanel.display();
		
	}
	
	public Observable getCoinReceiver(){
		return coinReceiver;
	}

	public void processMoneyReceived(int money){
		((CoinReceiver)coinReceiver).continueReceive();
	}
	
	/**
	 * Author : Lin
	 * update method for Observer.
	 * Observer updates its state based on the event.
	 * 
	 */
	@Override
	public void update(Observable o, Object arg) {
		
		if(!arg.equals("Refund Money")){
			System.out.println("@@@@@Observer: Update method of TransactionController");
			processMoneyReceived(((CoinReceiver)coinReceiver).getValue());
		}
	}
	
	public CustomerUI getCustomerPanel(){
		return this.customerPanel;
	}
	
	
	/**
	 * Author : Priyanka
	 * going to the next state of the Termination State 
	 * 
	 */
	public void nextState(int i) {
		if(!(incoming==i)){
		this.currentState.nextState(this);
		incoming=i;}
	}
	
	
	public TerminateState getCurrentState() {
		return currentState;
	}
	
	public void setCurrentState(TerminateState state) {
		this.currentState=state;
		
	}

	/**
	 * Author : Priyanka
	 * resetting the state
	 * 
	 */

	public void restartState() {
		this.currentState = new InitialState();
		incoming=0;
	}


	/**
	 * Author : Priyanka
	 * Template method for Termination.
	 * 
	 */
	public void TerminateFault()
	{		
		currentState.handleTermination(dispenseController,((CoinReceiver)coinReceiver));		
		((CoinReceiver)coinReceiver).setValue(0);
	}

	
	public DispenseController getDispenseController()
	{
		return dispenseController;
	}

	public MainController getMainController()
	{
		return mainController;
	}
	
	
}
